iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0

昨天簡單的講了Props,以及用Props內的handleChange舉了個例,相信大家對於“怎麼在React中使用TypeScript“,有多一點的認識。(我在開始寫文章前真的沒想到在React要使用TypeScript會這麼麻煩...)

今天,我們來看一下useEffect,老實說其實滿簡單的,在一般人的認知,useEffect就是拿來做"side effect"用的地方,side effect最常舉的例就是打api了。我們在元件渲染後,進到useEffect函式內,執行第一個引數(一個callback,通常是拿來打api),再將api傳回來的資料寫進state當中,進而讓React幫我們更改DOM,完成新的畫面渲染。並根據第二個引數:一個控管變數的陣列(dependencies),來決定在什麼時機點要重新執行這個callback function。

我想這應該是大家的認知吧。不過你有想過React是怎麼定義這個useEffect函式嗎?

讓我們在App.tsx內引入useEffect吧:

//在App.tsx中

import { useEffect } from "react"

const App = () => {

//請幫我對useEffect按下右鍵,並選"移至定義"!
useEffect(()=>{},[])

return <div>Whatever</div>
}

useEffect按下"移至定義"後,我們會跑到"index.d.ts",也就是型別宣告檔內,裡面有React開發者對於useEffect更詳盡的說明,超酷,而且超好懂。我沒有想過這個動作有這麼好用!

我們會看到下面這幾行

    /**
     * Accepts a function that contains imperative, possibly effectful code.
     *
     * @param effect Imperative function that can return a cleanup function
     * @param deps If present, effect will only activate if the values in the list change.
     *
     * @version 16.8.0
     * @see https://reactjs.org/docs/hooks-reference.html#useeffect
     */
    function useEffect(effect: EffectCallback, deps?: DependencyList): void;

這邊已經明確說明了第一個參數(他取名叫effect)是個命令式的函式,可以回傳一個清理函式(cleanup function好像怎麼翻都怪)、第二個參數deps是一旦存在,就會在deps當中任何值有改變時,effect才會執行。並且除了這些說明外,你還能看到當初寫下這些文字時,React的版本在第幾版、以及相關的網址,讓你進行後續查找。(厲害package)的型別宣告檔通常都會包含這些資訊。

好,回到跟TypeScript有關的部分,看剛剛的最後一行:
function useEffect(effect: EffectCallback, deps?: DependencyList): void;

effect的型別是EffectCallback,我們目前不知道他是什麼樣子,所以讓我們再對他執行一次"移至定義"吧!你會看到:

type EffectCallback = () => (void | Destructor);

啊哈,太好了,他就是一個函式,回傳值的型別是void(也就是不回傳任何值)或是Destructor
Destructor又是什麼呢?就是剛剛提到的清理函式啦,再移至定義吧:

type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };

Destructor又是一個函式,回傳值的型別也是void,或者{ [UNDEFINED_VOID_ONLY]: never },這一行是用來表示,這個物件是絕不可能會被回傳的,如果你真的回傳了這種東西,那TypeScript就會報錯,讓你避開這個錯誤,同樣的作法我們也能用在絕不可能會被執行到的switch statement

然後,我們也來看一下選擇性的deps的型別DependencyList定義吧:

type DependencyList = ReadonlyArray<unknown>;

啊哈,我們知道這個陣列應該要是個唯讀陣列,且裡面的值是unknown(不是any唷,其中差異可以再去翻閱之前的文章)。

最後,useEffect回傳值的型別是void。

同樣的做法你也能對其他Hooks進行定義上的查詢,你會發現,裡面用到的字彙都不會太難!有沒有覺得特別有趣呢?我們只是透過TypeScript,既然能了解到更多useEffect的實作知識呢!

useEffect是個相對簡單,沒什麼陷阱跟意外的hook,明天我們再來看看其他hook跟TypeScript的關係跟用法吧!


上一篇
第22天!TypeScript與React的Props!
下一篇
第24天!TypeScript 與 useRef!
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
janlin002
iT邦好手 1 級 ‧ 2023-03-20 11:42:26

寫得很清楚,學到了!! /images/emoticon/emoticon12.gif

Lin Chen iT邦新手 5 級 ‧ 2023-05-12 10:06:46 檢舉

有幫到你真是太好了!謝謝回覆

我要留言

立即登入留言